/*
 *    Copyright (c) 2018-2025, cloud All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 * Neither the name of the pig4cloud.com developer nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 * Author: cloud
 */
package com.fuyao.cloud.admin.message.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.tree.Tree;
import cn.hutool.core.lang.tree.TreeNode;
import cn.hutool.core.lang.tree.TreeUtil;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.csp.sentinel.util.AssertUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fuyao.cloud.admin.message.mapper.MessageManagementMapper;
import com.fuyao.cloud.admin.message.service.MessageCtiService;
import com.fuyao.cloud.admin.message.service.MessageReminderService;
import com.fuyao.cloud.admin.message.service.MessageUserobjectService;
import com.fuyao.cloud.common.data.datascope.DataScope;
import com.fuyao.cloud.message.dto.*;
import com.fuyao.cloud.message.entity.MessageCti;
import com.fuyao.cloud.message.entity.MessageManagement;
import com.fuyao.cloud.admin.message.service.MessageManagementService;
import com.fuyao.cloud.message.entity.MessageReminder;
import com.fuyao.cloud.message.vo.ManagementUserObjectVO;
import com.fuyao.cloud.message.vo.MessageRuleVO;
import lombok.AllArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.Serializable;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 消息管理
 *
 * @author liyue
 * @date 2022-04-22 17:27:38
 */
@Service
@AllArgsConstructor
public class MessageManagementServiceImpl extends ServiceImpl<MessageManagementMapper, MessageManagement> implements MessageManagementService {

    private final MessageCtiService messageCtiService;

    private final MessageReminderService messageReminderService;

    private final MessageUserobjectService userobjectService;

    @Override
    public boolean save(MessageManagementSaveDTO entity) {
        MessageManagement saveEntity = setEntityAttributes(entity);
        boolean hasSave = super.save(saveEntity);
        if (hasSave) {
            messageReminderService.saveOrUpdate(getReminderDTO(entity, saveEntity.getId()));
        }
        if (entity.getUserObject()!=null){
            MessageUserObjectSaveDTO userObjectSaveDTO =entity.getUserObject();
            userObjectSaveDTO.setManagementid(saveEntity.getId());
            userObjectSaveDTO.setSubject(saveEntity.getSubject());
            userobjectService.saveMessageUserObjectBatch(userObjectSaveDTO);
        }
        return hasSave;
    }

    @Override
    public boolean updateById(MessageManagementUpdateDTO entity) {
        MessageManagement updateEntity = setEntityAttributes(entity);
        boolean hasUpdate = super.updateById(updateEntity);
        if (hasUpdate) {
            messageReminderService.saveOrUpdate(getReminderDTO(entity, updateEntity.getId()));
        }
        return hasUpdate;
    }

    @Override
    public IPage<MessageManagementPageDTO> getMessageManagementPage(Page page, QueryWrapper queryWrapper) {
        MessageManagement management = (MessageManagement) queryWrapper.getEntity();
        queryWrapper.like(StrUtil.isNotEmpty(management.getSubject()), "subject", management.getSubject());
        queryWrapper.like(StrUtil.isNotEmpty(management.getDoctype()), "doctype", management.getDoctype());
        queryWrapper.like(StrUtil.isNotEmpty(management.getTimelimitType()), "TIMELIMIT_TYPE", management.getTimelimitType());
        queryWrapper.eq(ObjectUtil.isNotEmpty(management.getDeptId()), "dept_id", management.getDeptId());
        queryWrapper.eq(ObjectUtil.isNotEmpty(management.getCtiId()), "cti_Id", management.getCtiId());
        queryWrapper.eq("del_flag", 0);
        return this.baseMapper.getMessageManagementPage(page, queryWrapper);
    }

    @Override
    public List<Tree<Long>> selectTree() {
        List<MessageManagement> managements = this.getBaseMapper().selectList(Wrappers.emptyWrapper());
        List<Long> regionalOwnIdList = this.getBaseMapper().selectListByScope(Wrappers.emptyWrapper(), new DataScope()).stream()
                .map(MessageManagement::getDeptId).collect(Collectors.toList());
        List<TreeNode<Long>> collect = managements.stream()
                .sorted(Comparator.comparing(MessageManagement::getCreateTime)).map(m -> {
                    TreeNode<Long> treeNode = new TreeNode();
                    treeNode.setId(m.getId());
                    treeNode.setParentId(0L);
                    treeNode.setName(m.getSubject());
                    treeNode.setWeight(120L);
                    // 有权限不返回标识
                    Map<String, Object> extra = new HashMap<>(8);
                    extra.put("isLock", !regionalOwnIdList.contains(m.getDeptId()));
                    extra.put("createTime", m.getCreateTime());
                    treeNode.setExtra(extra);
                    return treeNode;
                }).collect(Collectors.toList());
        return TreeUtil.build(collect, 0L);
    }

    @Override
    public List<ManagementUserObjectVO> listManagementUserObjectMode(ManagementUserObjectSearchDTO searchDTO) {
        return this.baseMapper.listManagementUserObjectMode(searchDTO);
    }

    @Override
    public List<MessageRuleVO> listMsgRule(Long msgManagementId) {
        return this.baseMapper.listMsgRule(msgManagementId);
    }

    @Override
    public List<ManagementUserObjectVO> listManagement(ManagementUserObjectSearchDTO searchDTO) {
        return this.baseMapper.listManagement(searchDTO);
    }

    @Override
    public boolean removeById(Serializable id) {
        long count = this.messageReminderService.count(Wrappers.<MessageReminder>lambdaQuery().eq(MessageReminder::getManagementid, id));
        AssertUtil.isTrue(count == 0, "当前消息管理有关联消对象，无法删除。");
        return super.removeById(id);
    }

    private MessageManagement setEntityAttributes(MessageManagementSaveDTO entity) {
        MessageManagement management = new MessageManagement();
        BeanUtil.copyProperties(entity, management);
        if (ObjectUtil.isNotEmpty(entity.getCtiId())) {
            MessageCti cti = this.messageCtiService.getById(entity.getCtiId());
            management.setCtiName(cti.getName());
            management.setCtiFullcode(cti.getFullcode());
            management.setCtiFullname(cti.getFullname());
        }
        if (ArrayUtil.isAllNotNull(entity.getModes())) {
            management.setMode(CollUtil.join(CollUtil.newArrayList(entity.getModes()), ","));
        }

        return management;
    }

    private MessageReminderDTO getReminderDTO(MessageManagementSaveDTO entity, Long managementId) {
        return MessageReminderDTO.builder().
                messageManagementId(managementId).
                jobId(entity.getJobId()).
                jobName(entity.getJobName()).
                build();
    }
}
